﻿using System;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using ITAP.ShprossesBuilder.Utils;
using System.Reflection;
using ITAP.Core.Utils;

namespace ITAP.ShprossesBuilder
{
    /// <summary>
    /// Вывод ошибки в программе
    /// </summary>
    public class ExceptionHelper : Form
    {
        private TextBox textBoxErrorText;
        private Button buttonOK;
        private Label label1;
        private Button buttonMail;
        private Button buttonCopyToClipboard;

        private string ver;
        private string fullText;
        private string smallText;
        private ModelControl modelControl;
        /// <summary>
        /// Конструктор
        /// </summary>
        /// <param name="_ver">Версия системы</param>
        public ExceptionHelper(String _ver)
        {
            InitializeComponent();

            ver = _ver;
        }


        public void ExceptionLog(Exception exception, ModelControl modelControl)
        {
            this.modelControl = modelControl;
            fullText = this.GetFullStackTrace(exception);
            smallText = this.GetSmallStackTrace(exception);
            if (smallText.Length > 256)
                smallText = smallText.Substring(0, 256);

            textBoxErrorText.Text = fullText;
            base.ShowDialog();
        }

        private string GetFullStackTrace(Exception ex)
        {
            string stackString = "";
            stackString += ex.Message + "\r\n";
            stackString += "Stack trace: \r\n";
            stackString += ex.StackTrace + "\r\n";

            Exception innerException = ex.InnerException;
            while (innerException != null)
            {
                stackString += "\r\n";
                stackString += "Inner exception: \r\n";
                stackString += innerException.Message + "\r\n";
                stackString += "Stack trace: \r\n";
                stackString += innerException.StackTrace + "\r\n";
                innerException = innerException.InnerException;
            }
            return ver + "\r\n" + stackString;
        }

        private string GetSmallStackTrace(Exception ex)
        {
            string stackString = "";
            stackString += ex.Message + "\r\n";
            stackString += "Stack trace: \r\n";
            stackString += ex.StackTrace + "\r\n";
            return ver + "\r\n" + stackString;
        }

        private void InitializeComponent()
        {
            this.textBoxErrorText = new System.Windows.Forms.TextBox();
            this.buttonOK = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.buttonCopyToClipboard = new System.Windows.Forms.Button();
            this.buttonMail = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // textBoxErrorText
            // 
            this.textBoxErrorText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.textBoxErrorText.Location = new System.Drawing.Point(12, 33);
            this.textBoxErrorText.Multiline = true;
            this.textBoxErrorText.Name = "textBoxErrorText";
            this.textBoxErrorText.ReadOnly = true;
            this.textBoxErrorText.Size = new System.Drawing.Size(686, 379);
            this.textBoxErrorText.TabIndex = 0;
            // 
            // buttonOK
            // 
            this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.buttonOK.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.buttonOK.Location = new System.Drawing.Point(623, 418);
            this.buttonOK.Name = "buttonOK";
            this.buttonOK.Size = new System.Drawing.Size(75, 23);
            this.buttonOK.TabIndex = 1;
            this.buttonOK.Text = "ОК";
            this.buttonOK.UseVisualStyleBackColor = true;
            this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(9, 11);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(286, 13);
            this.label1.TabIndex = 2;
            this.label1.Text = "При работе приложения возникла следующая ошибка:";
            // 
            // buttonCopyToClipboard
            // 
            this.buttonCopyToClipboard.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.buttonCopyToClipboard.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.buttonCopyToClipboard.Location = new System.Drawing.Point(430, 418);
            this.buttonCopyToClipboard.Name = "buttonCopyToClipboard";
            this.buttonCopyToClipboard.Size = new System.Drawing.Size(187, 23);
            this.buttonCopyToClipboard.TabIndex = 3;
            this.buttonCopyToClipboard.Text = "Скопировать в буфер обмена";
            this.buttonCopyToClipboard.UseVisualStyleBackColor = true;
            this.buttonCopyToClipboard.Click += new System.EventHandler(this.buttonCopyToClipboard_Click);
            // 
            // buttonMail
            // 
            this.buttonMail.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.buttonMail.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
            this.buttonMail.Location = new System.Drawing.Point(237, 418);
            this.buttonMail.Name = "buttonMail";
            this.buttonMail.Size = new System.Drawing.Size(187, 23);
            this.buttonMail.TabIndex = 3;
            this.buttonMail.Text = "Отправить сообщение об ошибке";
            this.buttonMail.UseVisualStyleBackColor = true;
            this.buttonMail.Click += new System.EventHandler(this.buttonMail_Click);
            // 
            // ExceptionHelper
            // 
            this.ClientSize = new System.Drawing.Size(710, 447);
            this.Controls.Add(this.buttonMail);
            this.Controls.Add(this.buttonCopyToClipboard);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.buttonOK);
            this.Controls.Add(this.textBoxErrorText);
            this.Name = "ExceptionHelper";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "Ошибка приложения";
            this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.ExceptionHelper_FormClosed);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        private void buttonCopyToClipboard_Click(object sender, EventArgs e)
        {
            Clipboard.SetDataObject(textBoxErrorText.Text);
        }

        Microsoft.Office.Interop.Outlook.ApplicationClass objectMail = null;
        Microsoft.Office.Interop.Outlook.MailItem objectItem = null;

        private void buttonMail_Click(object sender, EventArgs e)
        {
            try
            {

                objectMail = new Microsoft.Office.Interop.Outlook.ApplicationClass();
                objectItem = objectMail.CreateItem(Microsoft.Office.Interop.Outlook.OlItemType.olMailItem) as Microsoft.Office.Interop.Outlook.MailItem;


                BinaryFormatter formatter = new BinaryFormatter();
                Stream stream = new MemoryStream();
                formatter.Serialize(stream, this.modelControl.ModelContainer);
                string shprossesPath = Assembly.GetExecutingAssembly().Location;
                shprossesPath = Path.GetDirectoryName(shprossesPath);
                string modelFileName = shprossesPath + "\\errorModel.spr";

                FileStream zippedStream = File.Create(modelFileName);
                Archiver.Zip(stream, zippedStream);
                zippedStream.Seek(0, SeekOrigin.Begin);
                stream.Close();
                zippedStream.Close();
                // return;


                string fileName = modelFileName;
                System.IO.TextWriter tw = new System.IO.StreamWriter(fileName, false);
                tw.Write(fullText);
                tw.Flush();
                tw.Close();
                tw.Dispose();

                objectItem.Subject = "Shprosses(error)";
                objectItem.To = "info@glasscad.ru";
                objectItem.Body = fullText;
                objectItem.Attachments.Add(fileName, Microsoft.Office.Interop.Outlook.OlAttachmentType.olByValue, 1, fileName);
                objectItem.Display(null);
            }
            catch (Exception)
            {
                ProcessStartInfo psi = new ProcessStartInfo();
                psi.UseShellExecute = true;
                psi.FileName = "mailto:info@glasscad.ru&subject=Shprosses(error)&body=" + smallText;
                Process.Start(psi);
            }
        }

        private void buttonOK_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void ExceptionHelper_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (objectMail != null)
                objectMail = null;
            if (objectItem != null)
                objectItem = null;
        }


    }

    /// <summary>
    /// Делегат вывода сообщений о ошибке
    /// </summary>
    /// <param name="message">Исключение</param>
    public delegate void DelegateExceptionLog(Exception message);
}
